package org.one.stone.soup.grfxML;

import java.awt.Color;
import java.awt.Graphics;

import org.one.stone.soup.math.IntMath;
import org.one.stone.soup.mjdb.data.field.BoolField;
import org.one.stone.soup.mjdb.data.field.FloatField;
import org.one.stone.soup.mjdb.data.field.IntField;
import org.one.stone.soup.mjdb.data.field.LockException;
import org.one.stone.soup.mjdb.data.field.Point2DField;
import org.one.stone.soup.xml.XmlElement;
  /*
 * Copyright 2000-2001 Wet-Wired.com Ltd.,
 * Portsmouth England
 * All rights reserved.
 */

/**
	*
	* @author Nik Cross
*/
public class GeometryArc extends Geometry{

	DataPoint windowField;
	DataPoint boundsField;

	BoolField visibleField;
	boolean visible;

	FloatField transparencyField;
	boolean transparent;

	DataColor colorField;
	Color color;

	BoolField filledField;
	boolean filled;


	Point2DField realOffsetField;
	Point2DField offsetField;
	Point2DField positionField;
	int x;
	int y;

	IntField radiusField;
	int diameter;

	IntField startField;
	int start;
	IntField sweepField;
	int sweep;
public GeometryArc(
		GrfxMLEngine engine,
		DataPoint windowF,
		DataPoint boundsF,
		BoolField visibleF,
		FloatField transparencyF,
		DataColor colorF,
		BoolField filledF,
		Point2DField positionF,
	Point2DField realOffsetF,
		Point2DField offsetF,
		IntField startSizeF,
		IntField sweepSizeF,
		IntField radiusF
		) {
	super(engine);

	windowField = windowF;
	boundsField = boundsF;
	visibleField = visibleF;
	transparencyField = transparencyF;
	colorField = colorF;
	filledField = filledF;
	positionField = positionF;
	offsetField = offsetF;
	realOffsetField = realOffsetF;
	startField = startSizeF;
	sweepField = sweepSizeF;
	radiusField = radiusF;

	process(true);
}
/**
 * contains method comment.
 */
public boolean contains(Point2DField point,Point2DField pointView) {
	if(visibleField.getValue()==false)
		return false;

	try{
		if(GrfxMLProcessor.distance( realOffsetField,point ) <= radiusField.getValue())
		{
			Point2DField vector = new Point2DField();

			GrfxMLProcessor.sub(point,realOffsetField,vector);
			int angle = IntMath.angle( vector.getValueX(),vector.getValueY() );

			if(angle>=start && angle<=start+sweep)
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		else
			return false;
	}catch(LockException le){}//dummy catch
	return false;
}
public void draw(Graphics grfx)
{
	if(visibleField.getValue()==false || transparencyField.getValue()==1)
		return;

	if(visibleField.hasChanged())
		process(true);
	else
		process(false);

	grfx.setClip(
		windowField.getValueXMin(),
		windowField.getValueYMin(),
		windowField.getValueX(),
		windowField.getValueY()
	);
	grfx.setColor(color);
	if(filled)
	{
		grfx.fillArc(x,y,diameter,diameter,360-start,-sweep);
	}
	else
	{
		grfx.drawArc(x,y,diameter,diameter,360-start,-sweep);
	}
}
private void process(boolean forced)
{
	if(forced==true)
	{
		color = GrfxMLProcessor.getColorFor(colorField);
		filled = filledField.getValue();
		visible = visibleField.getValue();

		x = positionField.getValueX()+offsetField.getValueX();
		y = positionField.getValueY()+offsetField.getValueY();

		int radius = radiusField.getValue();
		x-=radius;
		y-=radius;

		diameter = radius*2;

		boundsField.setValueXMin(x);
		boundsField.setValueYMin(y);

		boundsField.setValueXMax(x+diameter);
		boundsField.setValueYMax(y+diameter);

		boundsField.update();

		start=startField.getValue();
		sweep=sweepField.getValue();
	}
	else
	{
		if(colorField.hasChanged())
		{
			color = GrfxMLProcessor.getColorFor(colorField);
		}

		if(visibleField.hasChanged())
		{
			visible = visibleField.getValue();
		}

		if(filledField.hasChanged())
		{
			filled = filledField.getValue();
		}

		if(offsetField.hasChanged() || radiusField.hasChanged() || positionField.hasChanged())
		{
			x = positionField.getValueX()+offsetField.getValueX();
			y = positionField.getValueY()+offsetField.getValueY();

			try{
				boundsField.setValueX(x,this);
				boundsField.setValueY(y,this);
			}catch(LockException le){}//dummy catch

			int radius = radiusField.getValue();
			x-=radius;
			y-=radius;

			diameter = radius*2;

			boundsField.setValueXMin(x);
			boundsField.setValueYMin(y);

			boundsField.setValueXMax(x+diameter);
			boundsField.setValueYMax(y+diameter);

		}

		if(startField.hasChanged())
		{
			start = startField.getValue();
		}
		if(sweepField.hasChanged())
		{
			sweep = sweepField.getValue();
		}
	}
}
/**
 *
 * @return java.lang.String
 */
public XmlElement toXML() {
	XmlElement element = new XmlElement("Arc");

	if(getId()!=null)
		element.addAttribute("id",getId());

	element.addAttribute("visible",""+visibleField.getValue());

	element.addAttribute("x",""+x);
	element.addAttribute("y",""+y);

	element.addAttribute("red",""+colorField.getValueX());
	element.addAttribute("green",""+colorField.getValueY());
	element.addAttribute("blue",""+colorField.getValueZ());

	element.addAttribute("filled",""+filledField.getValue());

	element.addAttribute("diameter",""+diameter);
	element.addAttribute("start",""+start);
	element.addAttribute("sweep",""+sweep);

	XmlElement bounds = element.addChild("Clip");
	bounds.addAttribute( "x",""+windowField.getValueXMin() );
	bounds.addAttribute( "y",""+windowField.getValueYMin() );
	bounds.addAttribute( "width",""+windowField.getValueX() );
	bounds.addAttribute( "height",""+windowField.getValueY() );

	return element;
}

public boolean hasChanged()
{
	if(
	        windowField.hasChanged()==true ||
	        boundsField.hasChanged()==true ||
	        visibleField.hasChanged()==true ||
	        transparencyField.hasChanged()==true ||
	        colorField.hasChanged()==true ||
	        filledField.hasChanged()==true ||
	        positionField.hasChanged()==true ||
	        offsetField.hasChanged()==true ||
	        realOffsetField.hasChanged()==true ||
	        startField.hasChanged()==true ||
	        sweepField.hasChanged()==true ||
	        radiusField.hasChanged()==true
	)
	{
	    return true;
	}
	
	return false;
}

public void resetChanged()
{
    windowField.resetChanged();
    boundsField.resetChanged();
    visibleField.resetChanged();
    transparencyField.resetChanged();
    colorField.resetChanged();
    filledField.resetChanged();
    positionField.resetChanged();
    offsetField.resetChanged();
    realOffsetField.resetChanged();
    startField.resetChanged();
    sweepField.resetChanged();
    radiusField.resetChanged();
}

}
